using System.Collections.Generic;
using FishFillets.Model;
using FishFillets.Model.GameItems;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using FishFillets.GameComponents.Helpers;
using System;
using System.Linq;
using FishFillets.ObjectLogic;

namespace FishFillets.GameComponents
{
    /// <summary>
    /// Game component representing single level.
    /// </summary>
    public class LevelComponent : DrawableGameComponent
    {
        private readonly ContentManager manager;
        private readonly AssetHelper manager2;
        private SpriteBatch spriteBatch;
        private Camera2D cam;

        private Texture2D bg;
        private readonly List<ItemComponent> Items;
        private readonly List<FishComponent> Fishes;

        public readonly Level Level;

        protected TimeSpan timeBuildingUp = TimeSpan.Zero;

        public LevelComponent(Game game, Level level) 
            : base(game)
        {
            manager = new ContentManager(game.Services) { RootDirectory = "Content" };
            manager2 = new AssetHelper(Game.GraphicsDevice, manager.RootDirectory);
            this.Level = level;
            Items = new List<ItemComponent>();
            Fishes = new List<FishComponent>();
        }

        public override void Initialize()
        {
            // Initialize all items
            foreach (Item item in Level.Items)
            {
                ItemComponent itemComponent = new ItemComponent(Game, manager, manager2, item, Level.Name);
                Items.Add(itemComponent);
                itemComponent.Initialize();
            }

            // Initialize the big fish
            FishComponent fishComponent = new FishComponent(Game, manager, manager2, Level.Big, "big");
            Fishes.Add(fishComponent);
            fishComponent.Initialize();

            // Initialize the small fish
            fishComponent = new FishComponent(Game, manager, manager2, Level.Small, "small");
            Fishes.Add(fishComponent);
            fishComponent.Initialize();

            spriteBatch = new SpriteBatch(Game.GraphicsDevice);
            cam = new Camera2D();
            cam.Pos = new Vector2(300.0f, 200.0f);

            base.Initialize();
        }

        protected override void LoadContent()
        {
            foreach (ItemComponent item in Items)
            {
                item.SpriteBatch = spriteBatch;
            }
            foreach (FishComponent fish in Fishes)
            {
                fish.SpriteBatch = spriteBatch;
            }
            bg =  manager2.LoadTextureStream(string.Format("images/{0}/bg", Level.Name));
        }

        protected override void UnloadContent()
        {
            manager.Unload();
            manager2.UnloadAll();
            Items.Clear();
            Fishes.Clear();
        }

        public override void Update(GameTime gameTime)
        {
            // Keeping drawing frame rate at 1/10.
            timeBuildingUp += gameTime.ElapsedGameTime;
            if (timeBuildingUp < TimeSpan.FromMilliseconds(99))
                return;

            if (GameController.Instance.levelScript != null)
                GameController.Instance.levelScript.prog_update();

            foreach (FishComponent fish in Fishes.OrderBy((f) => f.UpdateOrder))
            {
                fish.Update(gameTime);
            }
            foreach (ItemComponent item in Items.OrderBy((i) => i.UpdateOrder))
            {
                item.Update(gameTime);
            }

            timeBuildingUp = TimeSpan.Zero;
            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
            //// if using XNA 4.0
            spriteBatch.Begin(SpriteSortMode.Deferred,
                                    BlendState.AlphaBlend,
                                    null,
                                    null,
                                    null,
                                    null,
                                    cam.get_transformation(spriteBatch.GraphicsDevice));
            //spriteBatch.Begin();

            spriteBatch.Draw(bg, new Rectangle(0, 0, bg.Width, bg.Height), null, Color.White, 0f,
                Vector2.Zero, SpriteEffects.None, 1f); // layerDepth - 0-1 from foreground to background
            foreach (ItemComponent item in Items.OrderBy((i) => i.DrawOrder))
            {
                item.Draw(gameTime);
            }
            foreach (FishComponent fish in Fishes.OrderBy((f) => f.DrawOrder))
            {
                fish.Draw(gameTime);
            }
            spriteBatch.End();
        }
    }
}
